import math
from cStringIO import StringIO

import Image
import ImageDraw
import ImageEnhance

#-------------------------------------------------------------------------------
def new_image(size, bg=None):
    bg = bg or (255, 255, 255)
    return Image.new('RGB', size, bg)
    
#-------------------------------------------------------------------------------
def image_from_bytes(bytes):
    img = Image.open(StringIO(bytes))
    if img.mode <> 'RGB':
        img = img.convert('RGB')
    
    return img

#-------------------------------------------------------------------------------
def thumbnail_from_image(img, size):
    '''
    Create a thumbnail image from the PIL ``img`` instance. ``size`` is 
    2-tuple of (x,y) values.
    '''
    width, height = img.size
    aspect_x, aspect_y = size
    
    crop_x = width
    crop_y = int(float(width) / aspect_x * aspect_y)
    if crop_y > height:
        crop_y = height
        crop_x = int(float(crop_y) / aspect_y * aspect_x)

    diff_x, diff_y = (width - crop_x) / 2, (height - crop_y) / 2
    box = (diff_x, diff_y, diff_x + crop_x, diff_y + crop_y)
    im_crop = img.crop(box)
    im_crop.thumbnail((aspect_x, aspect_y), Image.ANTIALIAS)

    return im_crop

#-------------------------------------------------------------------------------
def sample_image(x=200, y=200):
    img = new_image((x,y))
    draw = ImageDraw.Draw(img)

    #draw some axes and markers
    for i in range(x / 10):
        draw.line((i * 10 + 30, y - 15, i*10+30, 20), fill="#DDD")
        if i % 5 == 0:
            draw.text((i * 10 + 15, y - 15), `i * 10`, fill="#000")

    for j in range(1, y / 10 - 2):
        draw.text((0,y - 15 - j * 10), `j * 10`, fill="#000")

    draw.line((20, y - 19, x, y - 19), fill="#000")
    draw.line((19, 20, 19, y-18), fill="#000")
    return img

#-------------------------------------------------------------------------------
def resize_canvas(img, size):
    ax, ay = float(size[0]), float(size[1])
    aspect = ax / float(ay)
    oldx, oldy = img.size
    if oldx <= ax and oldy <= ay:
        img2 = new_image(size)
        img2.paste(img, (int((ax - oldx) / 2), int((ay - oldy) / 2))) # , img)
        #img2.convert('RGB').convert('P', palette=Image.ADAPTIVE)
        return img2
        
    ratio = oldx / float(oldy)
    if ratio > aspect:
        newx = oldx
        newy = int(math.ceil((newx * ay) / ax))
        box = (0, int(abs((oldy - newy) / 2)))
    else:
        newy = oldy
        newx = int(math.ceil((ax * newy) / ay))
        box = (int(abs((oldx - newx) / 2)), 0)
        
    img2 = new_image((newx, newy))
    img2.paste(img, box) #, img)
    return img2.resize(size, Image.ANTIALIAS)
    
    
#-------------------------------------------------------------------------------
def save_icon(path, bytes, size):
    thumb_image = resize_canvas(image_from_bytes(bytes), size)
    try:
        thumb_image.save(path, 'JPEG', quality=95)
    except Exception, why:
        raise


#-------------------------------------------------------------------------------
def reduce_opacity(im, opacity):
    """Returns an image with reduced opacity."""
    if opacity < 0 or opacity > 1:
        opacity = 0
    if im.mode != 'RGBA':
        im = im.convert('RGBA')
    else:
        im = im.copy()
    alpha = im.split()[3]
    alpha = ImageEnhance.Brightness(alpha).enhance(opacity)
    im.putalpha(alpha)
    return im

#-------------------------------------------------------------------------------
def watermark(im, mark, position, opacity=1):
    """Adds a watermark to an image."""
    if opacity < 1:
        mark = reduce_opacity(mark, opacity)

    if im.mode != 'RGBA':
        im = im.convert('RGBA')

    # create a transparent layer the size of the image and draw the
    # watermark in that layer.
    layer = Image.new('RGBA', im.size, (0,0,0,0))
    if position == 'tile':
        for y in range(0, im.size[1], mark.size[1]):
            for x in range(0, im.size[0], mark.size[0]):
                layer.paste(mark, (x, y))
    elif position == 'scale':
        # scale, but preserve the aspect ratio
        ratio = min(
            float(im.size[0]) / mark.size[0], float(im.size[1]) / mark.size[1])
        w = int(mark.size[0] * ratio)
        h = int(mark.size[1] * ratio)
        mark = mark.resize((w, h))
        layer.paste(mark, ((im.size[0] - w) / 2, (im.size[1] - h) / 2))
    else:
        layer.paste(mark, position)
    # composite the watermark with the layer
    return Image.composite(layer, im, layer)
    
################################################################################
if __name__ == '__main__':
    import sys
    im = resize_canvas(Image.open(sys.argv[1]).convert('RGBA'), (85,110))
    print im.size
    im.show()

